#!/bin/bash
# EbbFlow 配置文件生成器
# 用法: 设置环境变量 IP_LIST="ip1,ip2,ip3" && ./keygen.sh [OPTIONS]

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 默认配置
PORT_BASE=${PORT_BASE:-8000}  # 与 fabfile.py 中的 CONSENSUS_PORT 保持一致
OUTPUT_DIR=${OUTPUT_DIR:-etc}
OUTPUT_FILE="${OUTPUT_DIR}/conf.json"
GITEE_REPO=${GITEE_REPO:-"https://gitee.com/Yi_con/ebbflow.git"}
GITEE_BRANCH=${GITEE_BRANCH:-"master"}

# 从环境变量读取 IP 列表（必须）
IP_LIST=${IP_LIST:-""}

# 配置参数（可根据需要调整）
MAX_BATCH_SIZE=${MAX_BATCH_SIZE:-5000}
MAX_TX_SIZE=${MAX_TX_SIZE:-250}
SLEEP_TIMER=${SLEEP_TIMER:-50}
CLIENT_TIMER=${CLIENT_TIMER:-10000}
BROADCAST_TIMER=${BROADCAST_TIMER:-10000}
CONSENSUS_TYPE=${CONSENSUS_TYPE:-14}
RBC_TYPE=${RBC_TYPE:-1}

# 解析命令行参数
PUSH_TO_GITEE=false
SHOW_HELP=false

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            SHOW_HELP=true
            shift
            ;;
        -p|--push)
            PUSH_TO_GITEE=true
            shift
            ;;
        --port-base)
            PORT_BASE="$2"
            shift 2
            ;;
        --output-dir)
            OUTPUT_DIR="$2"
            OUTPUT_FILE="${OUTPUT_DIR}/conf.json"
            shift 2
            ;;
        --repo)
            GITEE_REPO="$2"
            shift 2
            ;;
        *)
            echo -e "${YELLOW}警告: 未知参数 '$1'${NC}"
            shift
            ;;
    esac
done

# 显示帮助信息
if [ "$SHOW_HELP" = true ]; then
    echo -e "${GREEN}EbbFlow 配置文件生成器${NC}"
    echo ""
    echo "用法:"
    echo "  export IP_LIST=\"ip1,ip2,ip3\" && ./keygen.sh [选项]"
    echo ""
    echo "环境变量 (必需):"
    echo "  IP_LIST            节点 IP 地址列表，逗号分隔 (例如: 192.168.1.1,192.168.1.2,192.168.1.3)"
    echo ""
    echo "环境变量 (可选):"
    echo "  FAULTY             容错节点数量 (如果不设置，将根据节点数自动计算: floor((n-1)/3))"
    echo "  FAULTY_COUNT       容错节点数量 (与 FAULTY 相同)"
    echo "  PORT_BASE          端口基础值 (默认: 8000)"
    echo "  MAX_BATCH_SIZE     最大批次大小 (默认: 30000)"
    echo "  OUTPUT_DIR         输出目录 (默认: etc)"
    echo ""
    echo "选项:"
    echo "  -h, --help         显示帮助信息"
    echo "  -p, --push         生成后自动推送到 gitee 仓库"
    echo "  --port-base         端口基础值 (覆盖环境变量)"
    echo "  --output-dir        输出目录 (覆盖环境变量)"
    echo "  --repo             Gitee 仓库地址"
    echo ""
    echo "容错数量计算:"
    echo "  默认根据节点数自动计算: faulty = floor((nodes_total - 1) / 3)"
    echo "  这是 BFT 共识算法的标准公式，确保 n >= 3f + 1"
    echo "  如果需要，可以通过环境变量 FAULTY 手动指定"
    echo ""
    echo "示例:"
    echo "  export IP_LIST=\"192.168.1.1,192.168.1.2,192.168.1.3\""
    echo "  ./keygen.sh  # 自动计算 faulty = floor((3-1)/3) = 0"
    echo ""
    echo "  export IP_LIST=\"192.168.1.1,192.168.1.2,192.168.1.3,192.168.1.4\""
    echo "  ./keygen.sh  # 自动计算 faulty = floor((4-1)/3) = 1"
    echo ""
    echo "  export IP_LIST=\"192.168.1.1,192.168.1.2,192.168.1.3\""
    echo "  export FAULTY=0"
    echo "  ./keygen.sh --push  # 手动指定 faulty = 0"
    echo ""
    exit 0
fi

# 验证 IP_LIST 环境变量
if [ -z "$IP_LIST" ]; then
    echo -e "${RED}错误: 必须设置环境变量 IP_LIST${NC}"
    echo ""
    echo "用法示例:"
    echo "  export IP_LIST=\"192.168.1.1,192.168.1.2,192.168.1.3\""
    echo "  ./keygen.sh"
    echo ""
    exit 1
fi

# 解析 IP 列表
IFS=',' read -ra IP_ARRAY <<< "$IP_LIST"
NODES_TOTAL=${#IP_ARRAY[@]}

if [ $NODES_TOTAL -eq 0 ]; then
    echo -e "${RED}错误: IP_LIST 为空或无效${NC}"
    exit 1
fi

# 自动计算容错数量（如果未通过环境变量指定）
# BFT 算法要求: n >= 3f + 1，所以 f = floor((n-1)/3)
if [ -z "${FAULTY}" ] && [ -z "${FAULTY_COUNT}" ]; then
    # 使用 bash 整数除法: $(( (n-1) / 3 ))
    FAULTY=$(( (NODES_TOTAL - 1) / 3 ))
    echo -e "${YELLOW}提示: 未指定 FAULTY，根据节点数自动计算: faulty = floor(($NODES_TOTAL - 1) / 3) = $FAULTY${NC}"
else
    # 如果通过环境变量指定，优先使用
    FAULTY=${FAULTY:-${FAULTY_COUNT:-1}}
    if ! [[ "$FAULTY" =~ ^[0-9]+$ ]]; then
        echo -e "${RED}错误: FAULTY 必须是有效的非负整数${NC}"
        exit 1
    fi
    FAULTY=$((FAULTY))  # 确保是整数
    echo -e "${GREEN}使用指定的容错数量: faulty = $FAULTY${NC}"
fi

# 验证容错数量
if [ "$FAULTY" -lt 0 ]; then
    echo -e "${RED}错误: FAULTY 不能为负数${NC}"
    exit 1
fi

# 验证 BFT 约束: n >= 3f + 1
MIN_NODES=$(( 3 * FAULTY + 1 ))
if [ "$NODES_TOTAL" -lt "$MIN_NODES" ]; then
    echo -e "${RED}错误: 节点数量 ($NODES_TOTAL) 不满足 BFT 约束${NC}"
    echo -e "${RED}       要求: n >= 3f + 1 = 3*$FAULTY + 1 = $MIN_NODES${NC}"
    echo -e "${YELLOW}提示: 请增加节点数量或减少容错数量${NC}"
    exit 1
fi

echo -e "${BLUE}================================================${NC}"
echo -e "${GREEN}EbbFlow 配置文件生成器${NC}"
echo -e "${BLUE}================================================${NC}"
echo ""
echo -e "${GREEN}节点总数 (nodes_total):${NC} $NODES_TOTAL"
echo -e "${GREEN}容错数量 (faulty):${NC} $FAULTY"
echo -e "${GREEN}端口基础值:${NC} $PORT_BASE"
echo -e "${GREEN}输出文件:${NC} $OUTPUT_FILE"
echo ""

# 创建输出目录
mkdir -p "$OUTPUT_DIR"

# 构建 replicas JSON 数组
REPLICAS_JSON="["
for i in "${!IP_ARRAY[@]}"; do
    IP="${IP_ARRAY[$i]}"
    PORT=$((PORT_BASE + i))
    NODE_ID=$i
    
    if [ $i -gt 0 ]; then
        REPLICAS_JSON+=","
    fi
    
    REPLICAS_JSON+=$'\n      {'
    REPLICAS_JSON+=$'\n         "id": "'"$NODE_ID"'",'
    REPLICAS_JSON+=$'\n         "host": "'"$IP"'",'
    REPLICAS_JSON+=$'\n         "port": "'"$PORT"'"'
    REPLICAS_JSON+=$'\n      }'
    
    echo -e "  节点 ${GREEN}$NODE_ID${NC}: $IP:${YELLOW}$PORT${NC}"
done
REPLICAS_JSON+=$'\n   ]'

# 生成配置文件
echo ""
echo -e "${BLUE}生成配置文件: ${OUTPUT_FILE}${NC}"
cat > "$OUTPUT_FILE" << EOF
{
   "maxBatchSize": ${MAX_BATCH_SIZE},
   "maxTxSize": ${MAX_TX_SIZE},
   "sleepTimer": ${SLEEP_TIMER},
   "clientTimer": ${CLIENT_TIMER},
   "broadcastTimer": ${BROADCAST_TIMER},
   "tParameter": 0,
   "verbose": true,
   "evalMode": 0,
   "evalInterval": 10,
   "cryptoOpt": 0,
   "local": false,
   "maliciousNode": false,
   "maliciousMode": 0,
   "maliciousNID": "",
   "splitPorts": false,
   "logOpt": 0,
   "consensus": ${CONSENSUS_TYPE},
   "RBCType": ${RBC_TYPE},
   "replicas": ${REPLICAS_JSON}
}
EOF

echo -e "${GREEN}配置文件生成成功!${NC}"
echo ""

# 显示配置摘要
echo -e "${BLUE}==================== 配置摘要 ====================${NC}"
echo -e "${GREEN}节点总数 (nodes_total):${NC} $NODES_TOTAL"
echo -e "${GREEN}容错数量 (faulty):${NC} $FAULTY"
echo -e "${GREEN}BFT 约束验证:${NC} n=$NODES_TOTAL >= 3f+1=$MIN_NODES ✓"
echo -e "${GREEN}端口基础值:${NC} $PORT_BASE"
echo ""
echo -e "${GREEN}节点列表:${NC}"
for i in "${!IP_ARRAY[@]}"; do
    echo "  节点 $i: ${IP_ARRAY[$i]}:$((PORT_BASE + i))"
done
echo -e "${BLUE}=================================================${NC}"
echo ""

# 显示生成的配置文件
echo -e "${BLUE}配置文件内容:${NC}"
cat "$OUTPUT_FILE"
echo ""

# 推送到 gitee（如果启用）
if [ "$PUSH_TO_GITEE" = true ]; then
    echo -e "${YELLOW}准备推送到 gitee 仓库...${NC}"
    
    # 检查是否在 git 仓库中
    if [ ! -d ".git" ]; then
        echo -e "${RED}错误: 当前目录不是 git 仓库${NC}"
        echo "请先初始化 git 仓库或克隆 gitee 仓库"
        exit 1
    fi
    
    # 检查 git 远程仓库是否已配置
    if ! git remote get-url origin > /dev/null 2>&1; then
        echo -e "${YELLOW}添加 gitee 远程仓库...${NC}"
        git remote add origin "$GITEE_REPO" || true
    fi
    
    # 检查文件是否被 gitignore 忽略
    if git check-ignore -q "$OUTPUT_FILE"; then
        echo -e "${YELLOW}提示: 配置文件被 .gitignore 忽略，使用 -f 选项强制添加${NC}"
        git add -f "$OUTPUT_FILE"
    else
        git add "$OUTPUT_FILE"
    fi
    
    # 提交更改
    COMMIT_MSG="Update config: ${NODES_TOTAL} nodes, faulty=${FAULTY}"
    if git diff --cached --quiet; then
        echo -e "${YELLOW}没有更改需要提交${NC}"
    else
        git commit -m "$COMMIT_MSG" || {
            echo -e "${RED}提交失败，请检查 git 配置${NC}"
            exit 1
        }
        echo -e "${GREEN}提交成功: $COMMIT_MSG${NC}"
    fi
    
    # 推送到远程仓库
    echo -e "${YELLOW}推送到 ${GITEE_REPO} (分支: ${GITEE_BRANCH})...${NC}"
    git push origin "$GITEE_BRANCH" || {
        echo -e "${RED}推送失败，请检查网络连接和权限${NC}"
        echo "你可以手动执行: git push origin $GITEE_BRANCH"
        exit 1
    }
    
    echo -e "${GREEN}配置文件已成功推送到 gitee 仓库!${NC}"
else
    echo -e "${YELLOW}提示: 使用 --push 选项可以自动推送配置文件到 gitee 仓库${NC}"
fi

echo ""
echo -e "${BLUE}================================================${NC}"
echo -e "${GREEN}完成!${NC}"
echo -e "${BLUE}================================================${NC}"